import arcade
import pymunk
import random


class Sprite(arcade.Sprite):
    def __init__(self, filename):
        super().__init__(filename)

    def update(self):
        if self.center_y < -10:
            self.remove_from_sprite_lists()


class MyGame(arcade.Window):
    def __init__(self, width, height, queue):
        super().__init__(width, height, '礼物展示盒')
        self.queue = queue
        self.queue.put(['小心心', 50, 0])
        self.queue.put(['辣条', 50, 0])
        # self.queue.put(['SC30', 10, 30])
        # self.queue.put(['SC50', 7, 50])
        # self.queue.put(['SC100', 5, 100])
        # self.queue.put(['SC500', 3, 500])
        # self.queue.put(['SC1000', 1, 1000])
        # self.queue.put(['B坷垃', 50, 10])
        # self.queue.put(['舰长', 10, 198])
        # self.queue.put(['粉丝团灯牌', 250, 1])
        # self.queue.put(['告白花束', 100, 3])
        # self.queue.put(['牛哇', 500, 1])
        # self.queue.put(['金币', 50, 5])
        # self.queue.put(['这个好诶', 100, 10])
        # self.queue.put(['泡泡糖', 310, 1])
        # self.queue.put(['打榜', 250, 1])
        # self.queue.put(['人气票', 100, 3])
        # self.queue.put(['樱花冰粉', 25, 10])
        # self.queue.put(['情书', 50, 5])
        # self.queue.put(['提督', 2, 19980])
        arcade.set_background_color(arcade.color.ELECTRIC_GREEN)
        self.giftList = []
        self.sprite_list = arcade.SpriteList()
        self.static_lines = []

        self.shape_being_dragged = None
        self.last_mouse_position = 0, 0
        self.draw_time = 0
        self.processing_time = 0
        self.physics_engine = arcade.PymunkPhysicsEngine(gravity=(0, -900))

        floor_height = 0
        body = pymunk.Body(body_type=pymunk.Body.STATIC)
        shape = pymunk.Segment(body, [-400, floor_height], [self.width + 400, floor_height], 0.0)
        shape.friction = 0.5
        shape.collision_type = 1
        self.physics_engine.space.add(shape, body)
        self.static_lines.append(shape)

        bodywall1 = pymunk.Body(body_type=pymunk.Body.STATIC)
        shapewall1 = pymunk.Segment(bodywall1, [-10, self.height], [-10, 400], 0.0)
        shapewall1.friction = 0
        shapewall1.collision_type = 1
        self.physics_engine.space.add(shapewall1, bodywall1)
        self.static_lines.append(shapewall1)

        bodywall2 = pymunk.Body(body_type=pymunk.Body.STATIC)
        shapewall2 = pymunk.Segment(bodywall2, [self.width + 10, self.height], [self.width + 10, 400], 0.0)
        shapewall2.friction = 0
        shapewall2.collision_type = 1
        self.physics_engine.space.add(shapewall2, bodywall2)
        self.static_lines.append(shapewall2)

        bodywall3 = pymunk.Body(body_type=pymunk.Body.STATIC)
        shapewall3 = pymunk.Segment(bodywall3, [-1000, self.height + 2000], [self.width + 1000, self.height + 2000], 0.0)
        shapewall3.friction = 0
        shapewall3.collision_type = 1
        self.physics_engine.space.add(shapewall3, bodywall3)
        self.static_lines.append(shapewall3)

        bodywall4 = pymunk.Body(body_type=pymunk.Body.STATIC)
        shapewall4 = pymunk.Segment(bodywall4, [-400, 0], [-800, 100], 0.0)
        shapewall4.friction = 0
        shapewall4.collision_type = 1
        self.physics_engine.space.add(shapewall4, bodywall4)
        self.static_lines.append(shapewall4)

        bodywall5 = pymunk.Body(body_type=pymunk.Body.STATIC)
        shapewall5 = pymunk.Segment(bodywall5, [self.width + 400, 0], [self.width + 800, 100], 0.0)
        shapewall5.friction = 0
        shapewall5.collision_type = 1
        self.physics_engine.space.add(shapewall5, bodywall5)
        self.static_lines.append(shapewall5)

    def on_draw(self):
        self.clear()
        self.sprite_list.draw()
        for line in self.static_lines:
            body = line.body
            pv1 = body.position + line.a.rotated(body.angle)
            pv2 = body.position + line.b.rotated(body.angle)
            arcade.draw_line(pv1.x, pv1.y, pv2.x, pv2.y, arcade.color.WHITE, 2)

    def on_mouse_press(self, x, y, button, modifiers):
        if button == arcade.MOUSE_BUTTON_LEFT:
            self.last_mouse_position = x, y
            shape_list = self.physics_engine.space.point_query((x, y), 150, pymunk.ShapeFilter())
            if len(shape_list) > 0:
                self.shape_being_dragged = list(filter(lambda x: x.shape.collision_type != 1, shape_list))
        elif button == arcade.MOUSE_BUTTON_RIGHT:
            self.physics_engine.space.gravity = (0, 900)

    def on_mouse_release(self, x, y, button, modifiers):
        if button == arcade.MOUSE_BUTTON_LEFT:
            self.shape_being_dragged = None
        elif button == arcade.MOUSE_BUTTON_RIGHT:
            self.physics_engine.space.gravity = (0, -900)

    def on_mouse_motion(self, x, y, dx, dy):
        if self.shape_being_dragged is not None:
            for shape in self.shape_being_dragged:
                self.last_mouse_position = x, y
                shape.shape.body.position = self.last_mouse_position
                shape.shape.body.velocity = dx * 20, dy * 20

    def on_update(self, delta_time):
        if not self.queue.empty():
            item = self.queue.get()
            if type(item) is tuple:
                arcade.set_background_color(item)
                return
            giftName, number, cost = item
            for i in range(number):
                self.giftList.append((giftName, cost))
        if self.giftList:
            giftName, cost = self.giftList.pop(random.choice(range(len(self.giftList))))
            x = random.randint(250, self.width - 250)
            y = self.height + random.randint(10, 100)
            sprite = Sprite(f'gift/{giftName}.png')
            sprite.set_position(x, y)

            self.sprite_list.append(sprite)
            self.physics_engine.add_sprite(sprite, collision_type='gift', mass=cost + 0.1)

        self.physics_engine.step()
        self.sprite_list.update()
        if self.shape_being_dragged is not None:
            for shape in self.shape_being_dragged:
                shape.shape.body.position = self.last_mouse_position
                shape.shape.body.velocity = 0, 0

    def set_background_color(self, color):
        arcade.set_background_color(color)
